﻿/* 迹I柳燕
 *
 * FileName:   XmlHelper.cs
 * Version:    2.0
 * Date:       2015.07.13
 * Author:     Ji
 *
 *========================================
 *
 * @namespace  Helper.JilyData
 * @class      XmlData
 *             XmlAction
 * @extends
 *
 *             对于Xml的保存和读取
 *
 *========================================

 * (http://www.jiailiuyan.com)
 *
 *
 *
 */

using System;
using System.IO;
using System.Windows;
using System.Xml.Serialization;

namespace Ji.DataHelper
{
    /// <summary> 保存和读取 xml 数据 </summary>
    public static class XmlData
    {
        /// <summary> 从XML读取数据 </summary>
        /// <typeparam name="T"> 读取的数据类型 </typeparam>
        /// <param name="fileInfo"> 包含数据的文件 FileInfo 信息 </param>
        /// <returns> 返回为 null 的时候读取失败 </returns>
        public static T ReadFromXml<T>(this FileInfo fileInfo)
        {
            return ReadFromXml<T>(fileInfo.FullName);
        }

        /// <summary> 从XML读取数据 </summary>
        /// <typeparam name="T"> 读取的数据类型 </typeparam>
        /// /// <param name="FullPath"> 包含数据的文件路径</param>
        /// <returns> Tpye = C ， 返回为null的时候读取失败 </returns>
        public static T ReadFromXml<T>(this string FullPath)
        {
            return XmlAction.Read<T>(FullPath);
        }

        /// <summary> 从XML读取数据 </summary>
        /// <typeparam name="T">  读取的数据类型 </typeparam>
        /// <param name="stream">包含数据的数据流 </param>
        /// <returns> Tpye = C ， 返回为null的时候读取失败 </returns>
        public static T ReadFromXml<T>(this Stream stream)
        {
            return XmlAction.Read<T>(stream);
        }

        public static object ReadFromXml(this Stream stream, Type type)
        {
            return XmlAction.Read(stream, type);
        }

        /// <summary> 写入数据到 XML </summary>
        /// <typeparam name="T"> 读取的数据类型 </typeparam>
        /// <param name="obj"> 将要写入的数据</param>
        /// <param name="fullpath"> 写 =入的文件路径 </param>
        /// <returns> 返回为 null 的时候写入成功 </returns>
        public static string WriteToXml<T>(this T obj, string fullpath)
        {
            try
            {
                FileHelper.CreatFile(fullpath);

                if (XmlAction.Save(obj, fullpath))
                {
                    return null;
                }
                else
                {
                    return "false";
                }
            }
            catch (Exception ex)
            {
                return ex.Message;
            }
        }

        public static Stream WriteDataToStream<T>(this T obj)
        {
            try
            {
                return XmlAction.SaveStream(obj);
            }
            catch { }
            return null;
        }
    }

    /// <summary> 封装对与Xml读写操作的类 </summary>
    internal static class XmlAction
    {
        internal static bool Save(object obj, string filePath)
        {
            return Save(obj, filePath, obj.GetType());
        }

        internal static bool Save(object obj, string filePath, System.Type type)
        {
            try
            {
                var memorystream = new MemoryStream();
                var writer = new StreamWriter(memorystream);
                var xs = new System.Xml.Serialization.XmlSerializer(type);
                xs.Serialize(writer, obj);
                var datas = new byte[memorystream.Length];
                memorystream.Position = 0;
                memorystream.Read(datas, 0, datas.Length);
                writer.Close();
                memorystream.Close();

                using (var fs = File.Create(filePath))
                {
                    fs.Write(datas, 0, datas.Length);
                    fs.Flush();
                }

                return true;
            }
            catch (Exception ex)
            {
                string dir = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments), "aSeeStudio", "savelogs");
                if (!Directory.Exists(dir))
                    Directory.CreateDirectory(dir);
                string path = Path.Combine(dir, DateTime.Now.ToString("yyyy-MM-dd-hh-mm-ss") + ".txt");
                StreamWriter sw = new StreamWriter(path);
                string w = ex.Message + "\r\n" + ex.StackTrace;
                sw.Write(w);
                sw.Close();
            }
            return false;
        }

        internal static Stream SaveStream(object obj)
        {
            var stream = new MemoryStream();
            var writer = new StreamWriter(stream);
            var xs = new XmlSerializer(obj.GetType());
            xs.Serialize(writer, obj);
            stream.Position = 0;
            return stream as Stream;
        }

        internal static T Read<T>(string filePath)
        {
            if (System.IO.File.Exists(filePath))
            {
                try
                {
                    using (var reader = new StreamReader(filePath))
                    {
                        var type = typeof(T);
                        var xs = new XmlSerializer(type);
                        object obj = xs.Deserialize(reader);
                        reader.Close();
                        return (T)obj;
                    }
                }
                catch { }
            }
            return default(T);
        }

        internal static object Read(Stream stream, Type type)
        {
            if (stream != null && stream.Length != 0)
            {
                try
                {
                    return (new XmlSerializer(type)).Deserialize(stream);
                }
                catch { }
            }
            return null;
        }

        internal static T Read<T>(Stream stream)
        {
            if (stream != null && stream.Length != 0)
            {
                try
                {
                    var type = typeof(T);
                    return (T)(new XmlSerializer(type)).Deserialize(stream);
                }
                catch { }
            }
            return default(T);
        }
    }
}